﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;
using System.Reflection;
using LinFu.AOP.Interfaces;

namespace BrainTechLLC
{
	public class LazyCreateWrapper : AroundMethodBase, IAroundInvoke
	{
		// TODO: Performance improvement
		protected override void Execute(IInvocationContext context, CutpointType when, object returnValue)
		{
			if (when != CutpointType.Before || !context.TargetMethod.Name.Contains("get_"))
				return;

			object thisObject = context.Target;			
			string propInfoName = context.TargetMethod.Name.Substring(4);
			Type t = thisObject.GetType();
			PropInfo propInfo = t.GetPropInfo(propInfoName);
			LazyCreateAttribute[] attrs = propInfo.GetAttributes<LazyCreateAttribute>();

			if (attrs != null && attrs.Length > 0)
			{
				IModifiableType mod = thisObject as IModifiableType;					
				mod.IsInterceptionDisabled = true;
				object oldValue = propInfo.GetValue(thisObject);
				if (oldValue == null)
				{
					Type propType = propInfo.PropertyDescriptor.PropertyType;
					ConstructorInfo constructor = propType.GetConstructor(System.Type.EmptyTypes);
					object newValue = constructor.Invoke(null);
					mod.IsInterceptionDisabled = false;	
					propInfo.PropertyInfo.SetValue(thisObject, newValue, null);					
				}
				mod.IsInterceptionDisabled = false;	
			}
		}
	}
}

